#include <syscall.h>
#include <vfs.h>
#include <stdio.h>
#include <malloc.h>
#include <cJSON.h>

extern int main(int argc, char *argv[], char *envp[]);
extern void do_init_mem();

extern volatile unsigned long __bss_start[];
extern volatile unsigned long __bss_end[];

static void clear_bss()
{
	for (int i = 0; i < __bss_end - __bss_start; i++)
	{
		__bss_start[i] = 0;
	}
}

static char **creat_string_array(cJSON *array)
{
	if (!array || !cJSON_IsArray(array))
		return NULL;

	int count = cJSON_GetArraySize(array);
	char **v = NULL;
	if (count)
	{
		v = malloc(sizeof(char *) * (count + 1));
	}

	const cJSON *item;
	int i = 0;
	cJSON_ArrayForEach(item, array)
	{
		char *s = cJSON_GetStringValue(item);
		v[i] = s;
		i++;
	}
	v[i] = NULL;
	return v;
}

void _start_c(char *env)
{
	clear_bss();
	do_init_mem();
	do_vfs_init();

	cJSON *root = cJSON_Parse(env);
	cJSON *arg_json = cJSON_GetObjectItemCaseSensitive(root, "arg");
	cJSON *env_json = cJSON_GetObjectItemCaseSensitive(root, "env");

	int argc = (arg_json && cJSON_IsArray(arg_json)) ? cJSON_GetArraySize(arg_json) : 0;
	char **argv = creat_string_array(arg_json);
	char **envp = creat_string_array(env_json);

	int ret = main(argc, argv, envp);

	cJSON_Delete(root);
	usys_process_exit(ret);
	return;
}
